﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ECare.Client.templates;

using ECare.BUS.Data;
using ECare.BUS;
using ECare.Client.controls;

namespace ECare.Client.frms
{
    public partial class frmFomulaInfo : frmNull
    {
        public frmFomulaInfo()
        {
            InitializeComponent();
            this.Load += frmFomulaInfo_Load;
            this.grd.CellMouseDown += grd_CellMouseDown;
        }

        void grd_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex < 0)
                return;

            var selectedItem = this.grd.Rows[e.RowIndex].DataBoundItem as ResoucesInfo;

            if (selectedItem == null)
                return;
            this.grd.DoDragDrop(selectedItem, DragDropEffects.Copy);




        }



        void frmFomulaInfo_Load(object sender, EventArgs e)
        {
            this.LoadResources();
            LoadInforamtion();
        }

        private void LoadInforamtion()
        {

            if (this.entity == null)
                return;

            this.txtCode.Text = this.entity.FormulaCode;
            this.txtName.Text = this.entity.FormulaName;
            this.cbActive.Checked = this.entity.IsActive;
            this.txtRemark.Text = this.entity.FormulaRemark;

            


            foreach (var detail in this.entity.Details.OrderBy(a=>a.Order))
            {
                var resource = this.DataSource.FirstOrDefault(a => a.ResourceId == detail.ResourceId);
                if (resource == null)
                    continue;
                this.AddResource(resource,detail.CarNumber,detail.Ischangecar,detail.Number);
            }
        }

        public BindingList<ResoucesInfo> DataSource { get; set; }
        public List<ucResoucesInfo> controls { get; set; }
        private void LoadResources()
        {
            DataSource = new BindingList<ResoucesInfo>(ResourcesHelper.GetAllResources());
            this.grd.DataSource = DataSource;

            controls = new List<ucResoucesInfo>();

        }

        public FormulaInfo entity { get; set; }
        public List<ucResoucesInfo> details = new List<ucResoucesInfo>();

        public event EntitySavedHandler Saved;
        private void btnSave_Click(object sender, EventArgs e)
        {

            RefreshControls();

            #region validate
            if (string.IsNullOrEmpty(this.txtName.Text))
            {
                this.errorProvider1.SetError(this.txtName, "?");
                return;
            }
            else
            {
                this.errorProvider1.SetError(this.txtName, string.Empty);
            }

            if (string.IsNullOrEmpty(this.txtCode.Text))
            {
                this.errorProvider1.SetError(this.txtCode, "?");
                return;
            }
            else
            {
                this.errorProvider1.SetError(this.txtCode, string.Empty);
            }
            #endregion

            



            foreach (var control in this.controls)
            {
                if (!control.ValidateNumber())
                    return;
            }

            if (this.entity == null)
            {

                //check if name is depculted


                this.entity = new FormulaInfo();
                this.entity.FormulaCode = this.txtCode.Text;
                this.entity.FormulaName = this.txtName.Text;
                this.entity.FormulaRemark = this.txtRemark.Text;
                this.entity.IsActive = this.cbActive.Checked;
                this.entity.Details = new List<FormulaDetail>();
                this.entity.DateCreated = DateTime.Now;
                var checkresult=FormulaHelper.CheckFormulaName(entity);
                if (!checkresult)
                {
                    this.errorProvider1.SetError(this.txtName, "配方名称重复");
                    return;
                }
                else
                {
                    this.errorProvider1.SetError(this.txtName, string.Empty);
                }


                foreach (var control in this.controls)
                {
                    var newdetail = new FormulaDetail();
                    newdetail.Order = control.Order;
                    newdetail.Number = control.GetNumber();
                    newdetail.ResourceId = control.CurrentResource.ResourceId;

                    newdetail.CarNumber = control.GetCarNumber();
                    newdetail.Ischangecar = control.GetIsChangeCar();

                    this.entity.Details.Add(newdetail);
                }
                this.entity.FormulaId = FormulaHelper.CreateFormula(this.entity);
            }
            else
            {


                string oldformulaname = this.entity.FormulaName;

                this.entity.FormulaCode = this.txtCode.Text;
                this.entity.FormulaName = this.txtName.Text;
                this.entity.FormulaRemark = this.txtRemark.Text;
                this.entity.IsActive = this.cbActive.Checked;
                if (oldformulaname != this.txtName.Text)
                {
                    //check if the newname is duplicated.
                    var checkresult = FormulaHelper.CheckFormulaName(entity);
                    if (!checkresult)
                    {
                        this.errorProvider1.SetError(this.txtName, "配方名称重复");
                        return;
                    }
                    else
                    {
                        this.errorProvider1.SetError(this.txtName, string.Empty);
                    }

                }



                this.entity.FormulaCode = this.txtCode.Text;
                this.entity.FormulaName = this.txtName.Text;
                this.entity.FormulaRemark = this.txtRemark.Text;
                this.entity.IsActive = this.cbActive.Checked;
                this.entity.Details = new List<FormulaDetail>();
                foreach (var control in this.controls)
                {
                    var newdetail = new FormulaDetail();
                    newdetail.Order = control.Order;
                    newdetail.Number = control.GetNumber();
                    newdetail.ResourceId = control.CurrentResource.ResourceId;

                    newdetail.CarNumber = control.GetCarNumber();
                    newdetail.Ischangecar = control.GetIsChangeCar();


                    this.entity.Details.Add(newdetail);
                }
                FormulaHelper.UpdateFormula(this.entity);
            }

            if (this.Saved != null)
                this.Saved(this.entity);

                    this.Close();
        }

        private void splitContainer2_Panel1_DragDrop(object sender, DragEventArgs e)
        {

            var resource = (ResoucesInfo)e.Data.GetData(typeof(ResoucesInfo));
            this.AddResource(resource);
        }

        private void AddResource(ResoucesInfo resource, int carnumber=1, bool ischangecar=false, decimal value = 0)
        {
            var newdetail = new ucResoucesInfo();
            newdetail.Order = this.splitContainer2.Panel1.Controls.Count;
            newdetail.ResourceCode = resource.ResourceCode;
            newdetail.ResourceId = resource.ResourceId;
            newdetail.Number = value;
            newdetail.CurrentResource = resource;
            newdetail.CarNumber = carnumber;
            newdetail.IsChangeCar = ischangecar;

            newdetail.LoadInformation();

            newdetail.Left = 5;
            newdetail.Top = newdetail.Order * 50;
            newdetail.Removed += newdetail_Removed;
            newdetail.UpCompelted += newdetail_UpCompelted;
            newdetail.DownCompleted += newdetail_DownCompleted;
            this.splitContainer2.Panel1.Controls.Add(newdetail);

            controls.Add(newdetail);
            this.DataSource.Remove(resource);
        }


        void newdetail_DownCompleted(ResoucesInfo resource, ucResoucesInfo control)
        {
            int currentIndex = control.Order;

            if (currentIndex == controls.Count - 1)
                return;

            var tempcontrol = this.controls.FirstOrDefault(a => a.Order == currentIndex + 1);

            control.Top = (currentIndex + 1) * 50;
            control.Order = control.Order + 1;
            control.SetOrder(control.Order);


            tempcontrol.Top = (tempcontrol.Order - 1) * 50;
            tempcontrol.Order = tempcontrol.Order - 1;
            tempcontrol.SetOrder(tempcontrol.Order);


            Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y + 50);
        }

        void newdetail_UpCompelted(ResoucesInfo resource, ucResoucesInfo control)
        {
            //throw new NotImplementedException();

            int currentIndex = control.Order;

            if (currentIndex == 0)
                return;

            var tempcontrol = this.controls.FirstOrDefault(a => a.Order == currentIndex - 1);

            control.Top = (currentIndex - 1) * 50;
            control.Order = control.Order - 1;
            control.SetOrder(control.Order);


            tempcontrol.Top = (tempcontrol.Order + 1) * 50;
            tempcontrol.Order = tempcontrol.Order + 1;
            tempcontrol.SetOrder(tempcontrol.Order);


            Cursor.Position = new Point(Cursor.Position.X, Cursor.Position.Y - 50);
        }


        private void RefreshControls()
        {
            var controls = this.controls.OrderBy(a => a.Order).ToList();

            this.splitContainer2.Panel1.Controls.Clear();

            int i = 1;
            foreach (var control in controls)
            {
                control.Left = 5;
                control.Top = (i-1) * 50;
                control.Order = i;
                this.splitContainer2.Panel1.Controls.Add(control);
                
                i++;
            }
        }


        void newdetail_Removed(ResoucesInfo resource, ucResoucesInfo control)
        {
            this.splitContainer2.Panel1.Controls.Remove(control);
            controls.Remove(control);


            this.DataSource.Add(resource);


            this.ReOrderControls();

        }


        private void ReOrderControls()
        {
            var orderedControls = controls.OrderBy(a => a.Order);

            for (int i = 0; i < orderedControls.Count(); i++)
            {
                var detail = this.splitContainer2.Panel1.Controls[i] as ucResoucesInfo;
                detail.SetOrder(i);
                detail.Left = 5;
                detail.Top = detail.Order * 50;
            }
        }


        private void splitContainer2_Panel1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(ResoucesInfo)))
                e.Effect = DragDropEffects.Copy;
            else
                e.Effect = DragDropEffects.None;

        }

        private void txtName_Leave(object sender, EventArgs e)
        {
            bool flag;

            if (this.entity == null)
            {
                var newformula = new FormulaInfo
                {
                    FormulaName = this.txtName.Text,
                };
                flag = FormulaHelper.CheckFormulaName(newformula);
            }
            else
            {
                var editformula = this.entity as FormulaInfo;
                editformula.FormulaName = this.txtName.Text;
                flag = FormulaHelper.CheckFormulaName(editformula);
            }
            if (!flag)
            {
                this.errorProvider1.SetError(this.txtName, "This formula name has existed.");
            }
            else
            {
                this.errorProvider1.Clear();
            }
        }

        private void txtName_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
